﻿using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Runtime.Serialization.Json;
using System.Text;
using Wulong.Phone.Utils.Rx;

namespace Wulong.Phone.Utils
{
    public class IsolatedStorageHelper
    {
        public static IObservable<T> GetObject<T>(string key)
        {
            return new AnonymousObservable<T>(observer =>
                                                  {
                                                      if (IsolatedStorageSettings.ApplicationSettings.Contains(key))
                                                      {
                                                          string serializedObject = IsolatedStorageSettings.ApplicationSettings[key].ToString();
                                                          observer.OnNext(Deserialize<T>(serializedObject));
                                                      }

                                                      observer.OnNext(default(T));
                                                      observer.OnCompleted();
                                                      return Disposable.Empty;
                                                  });
        }

        public static void SaveObject<T>(string key, T objectToSave)
        {
            var str = Serialize(objectToSave)
                .ObserveOnDispatcher()
                .Subscribe(serializedObject=>
                                            {
                                            IsolatedStorageSettings.ApplicationSettings[key] = serializedObject;  
                                            });
        }

        public static void DeleteObject(string key)
        {
            IsolatedStorageSettings.ApplicationSettings.Remove(key);
        }

        private static IObservable<string> Serialize(object objectToSerialize)
        {
            return new AnonymousObservable<string>(observer =>
                                                       {
                                                           using (var ms = new MemoryStream())
                                                           {
                                                               var serializer =
                                                                   new DataContractJsonSerializer(
                                                                       objectToSerialize.GetType());
                                                               serializer.WriteObject(ms, objectToSerialize);
                                                               ms.Position = 0;

                                                               using (var reader = new StreamReader(ms))
                                                               {
                                                                   observer.OnNext(reader.ReadToEnd());
                                                               }
                                                           }
                                                           observer.OnCompleted();
                                                           return Disposable.Empty;
                                                       });
        }

        private static T Deserialize<T>(string jsonString)
        {
            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
            {
                var serializer = new DataContractJsonSerializer(typeof(T));
                return (T)serializer.ReadObject(ms);
            }
        }
    }
}
